<template>
	<div class="home-container layout-pd">
		<el-row :gutter="15" class="home-card-one mb15">
			<el-col
				:xs="24"
				:sm="12"
				:md="12"
				:lg="6"
				:xl="6"
				v-for="(v, k) in state.homeOne"
				:key="k"
				:class="{ 'home-media home-media-lg': k > 1, 'home-media-sm': k === 1 }"
				style="max-width: 20%"
			>
				<div class="home-card-item flex" style="display: flex">
					<div class="flex-margin flex w100" :class="`home-one-animation${k}`">
						<div class="home-card-item-icon flex" :style="{ background: `var(${v.color2})` }">
							<img :src="v.icon" alt="tub" />
						</div>
						<div class="flex-auto" style="text-align: center">
							<span class="font20" style="font-weight: 700">{{ v.num1 }}</span>
							<div class="mt17">{{ v.num3 }}</div>
						</div>
					</div>
				</div>
			</el-col>
		</el-row>
		<el-row :gutter="15" class="home-card-two mb15">
			<el-col :xs="24" :sm="14" :md="14" :lg="16" :xl="16" style="max-width: 52%">
				<div class="home-card-item">
					<div style="height: 100%" ref="homeLineRef"></div>
				</div>
			</el-col>
			<el-col :xs="24" :sm="10" :md="10" :lg="8" :xl="8" style="max-width: 46%; flex: 1">
				<div class="home-card-item" style="width: 100%">
					<div style="height: 100%" ref="homePieRef"></div>
				</div>
			</el-col>
		</el-row>
		<el-row :gutter="15" class="home-card-three">
			<el-col :xs="24" :sm="14" :md="14" :lg="16" :xl="16" class="home-media" style="max-width: 52%">
				<div class="home-card-item">
					<div class="home-card-item-title">实时挂号</div>
					<el-table :data="appointmentData" style="width: 100%;" height="250">
						<el-table-column prop="img" label="头像" width="70" align="center">
							<template #default="scope">
								<el-image
									:src="scope.row.img || defaultAvatar"
									style="width: 35px; height: 35px; border-radius: 50%"
									:preview-src-list="[scope.row.img && scope.row.img !== 'null' ? scope.row.img : defaultAvatar]"
									:initial-index="0"
									fit="cover"
									preview-teleported
								>
									<template #error>
										<el-image
											:src="defaultAvatar"
											style="width: 35px; height: 35px; border-radius: 50%"
											:preview-src-list="[defaultAvatar]"
											:initial-index="0"
											fit="cover"
											preview-teleported
										></el-image>
									</template>
								</el-image>
							</template>
						</el-table-column>
						<el-table-column prop="name" label="患者姓名" width="100" align="center" />
						<el-table-column prop="tel" label="患者手机号" width="120" align="center" />
						<el-table-column prop="depart_name" label="挂号科室" width="100" align="center" />
						<el-table-column prop="price" label="挂号费" width="80" align="center" />
						<el-table-column prop="reser_time" label="挂号时间" width="140" align="center" />
					</el-table>
				</div>
			</el-col>
			<div :xs="24" :sm="10" :md="10" :lg="8" :xl="8" style="width: 45%; display: flex;margin-left: 6px;">
				<div class="home-card-item" style="margin-right: 7px;">
					<div class="home-card-item-title">热门科室</div>
					<el-table :data="departmentData" style="width: 100%" height="250">
						<el-table-column prop="index" label="排名" width="66" align="center">
							<template #default="scope">
								<span class="ranking-number">{{ scope.row.index }}</span>
							</template>
						</el-table-column>
						<el-table-column prop="name" label="科室" align="center">
							<template #default="scope">
								<span class="department-name">{{ scope.row.name }}</span>
							</template>
						</el-table-column>
						<el-table-column prop="count" label="挂号量" align="center" />
					</el-table>
				</div>
				<div class="home-card-item">
					<div class="home-card-item-title">热门医生</div>
					<el-table :data="doctorData" style="width: 100%" height="250">
						<el-table-column prop="index" label="排名" width="60">
							<template #default="scope">
								<span class="ranking-number">{{ scope.row.index }}</span>
							</template>
						</el-table-column>
						<el-table-column prop="name" label="医生姓名" width="100" align="center" />
						<el-table-column prop="count" label="挂号量" align="center" />
					</el-table>
				</div>
			</div>
		</el-row>
	</div>
</template>

<script setup lang="ts" name="home">
import { reactive, onMounted, ref, watch, nextTick, onActivated, markRaw } from 'vue';
import * as echarts from 'echarts';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { useUserInfo } from '/@/stores/userInfo';
import { dataList, appointmentList, departmentList, doctorList } from '/@/api/home/index';
import { ElMessage } from 'element-plus';
import { Session } from '/@/utils/storage';
import defaultAvatar from '/@/assets/cry.jpg';

let url='https://yiliao.kuxia.top'

// 处理图片加载错误的情况
const handleImageError = (row: any) => {
	row.img = defaultAvatar;
};

interface Appointment {
	img: string;
	name: string;
	tel: string;
	depart_name: string;
	price: string;
	reser_time: string;
}

interface Department {
	index: number;
	name: string;
	count: number;
}

interface Doctor {
	index: number;
	name: string;
	department: string;
	count: number;
}

// 获取实时挂号数据
const getAppointmentList = async () => {
	try {
		const res = await appointmentList().signIn({});
		console.log(res);

		if (res.code === 1) {
			// 将返回的数据映射到表格需要的格式
			appointmentData.value = res.data.map((item: any, index: number) => ({
				img: item.img ? (item.img.startsWith('http') ? item.img : url + item.img) : '',
				name: item.user_name || '',
				tel: item.tel || '',
				depart_name: item.depart_name || '',
				price: item.price || '0',
				reser_time: item.reser_time || '',
			}));
		} else {
			ElMessage.error(res.msg || '挂号数据获取失败');
		}
	} catch (error) {
		console.error('获取挂号数据失败:', error);
		ElMessage.error('挂号数据获取失败');
	}
};

// 获取热门科室数据 - 按heat字段从大到小排序
const getDepartmentList = async () => {
	try {
		const res = await departmentList().signIn({});

		if (res.code === 1) {
			// 先按heat字段从大到小排序，再映射到表格需要的格式
			const sortedData = [...res.data].sort((a: any, b: any) => {
				// 处理可能的undefined值，确保排序稳定性
				const heatA = a.heat ?? 0;
				const heatB = b.heat ?? 0;
				return heatB - heatA;
			});

			// 映射排序后的数据并添加排名，限制最多4条
			departmentData.value = sortedData.map((item: any, index: number) => ({
				index: index + 1,
				name: item.name || '',
				count: item.register_count || 0,
			}));
		} else {
			ElMessage.error(res.msg || '科室数据获取失败');
		}
	} catch (error) {
		console.error('获取科室数据失败:', error);
		ElMessage.error('科室数据获取失败');
		// 设置一些示例数据以便调试
		departmentData.value = [
			{ index: 1, name: '内科', count: 42 },
			{ index: 2, name: '外科', count: 38 },
			{ index: 3, name: '儿科', count: 26 },
			{ index: 4, name: '眼科', count: 18 },
			{ index: 5, name: '皮肤科', count: 15 },
		];
	}
};

// 获取热门医生数据 - 按heat字段从大到小排序
const getDoctorList = async () => {
	try {
		const res = await doctorList().signIn({});

		if (res.code === 1) {
			// 先按heat字段从大到小排序，再映射到表格需要的格式
			const sortedData = [...res.data].sort((a: any, b: any) => {
				// 处理可能的undefined值，确保排序稳定性
				const heatA = a.heat ?? 0;
				const heatB = b.heat ?? 0;
				return heatB - heatA;
			});

			// 映射排序后的数据并添加排名，限制最多4条
			doctorData.value = sortedData.map((item: any, index: number) => ({
				index: index + 1,
				name: item.name || '',
				department: item.department_name || '',
				count: item.visit_count || 0,
			}));
		} else {
			ElMessage.error(res.msg || '医生数据获取失败');
		}
	} catch (error) {
		console.error('获取医生数据失败:', error);
		ElMessage.error('医生数据获取失败');
	}
};

// 定义变量内容
const homeLineRef = ref();
const homePieRef = ref();
const homeBarRef = ref();
const appointmentData = ref<Appointment[]>([]);
const departmentData = ref<Department[]>([]);
const doctorData = ref<Doctor[]>([]);
const storesTagsViewRoutes = useTagsViewRoutes();
const storesThemeConfig = useThemeConfig();
const storesUserInfo = useUserInfo();
const { themeConfig } = storeToRefs(storesThemeConfig);
const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
const { userInfos } = storeToRefs(storesUserInfo);

const state = reactive({
	global: {
		homeChartOne: null,
		homeChartTwo: null,
		homeCharThree: null,
		dispose: [null, '', undefined],
	} as any,
	homeOne: [
		{
			num1: '0',
			num3: '今日预约人数',
			icon: new URL('../../assets/order_num.png', import.meta.url).href,
			color2: '--next-color-primary-lighter',
		},
		{
			num1: '0',
			num3: '今日消费人数',
			icon: new URL('../../assets/pay_num.png', import.meta.url).href,
			color2: '--next-color-success-lighter',
		},
		{
			num1: '0',
			num3: '今日就诊人数',
			icon: new URL('../../assets/create_card.png', import.meta.url).href,
			color2: '--next-color-warning-lighter',
		},
		{
			num1: '0',
			num3: '今日报告人数',
			icon: new URL('../../assets/total_pay.png', import.meta.url).href,
			color2: '--next-color-danger-lighter',
		},
		{
			num1: '0',
			num3: '今日总收入',
			icon: new URL('../../assets/hosptial_num.png', import.meta.url).href,
			color2: '--next-color-info-lighter',
		},
	],

	myCharts: [] as EmptyArrayType,
	charts: {
		theme: '',
		bgColor: '',
		color: '#303133',
	},
});

// 获取首页数据
const getDataList = async () => {
	try {
		// 检查是否有token
		const token = Session.get('token');
		if (!token) {
			ElMessage.warning('未登录或登录已过期，请重新登录');
			return;
		}

		const res = await dataList().signIn({});
		if (res.code === 1) {
			// 更新顶部统计数据
			state.homeOne[0].num1 = res.data.register || '0';
			state.homeOne[1].num1 = res.data.pay || '0';
			state.homeOne[2].num1 = res.data.visit || '0';
			state.homeOne[3].num1 = res.data.report || '0';
			state.homeOne[4].num1 = res.data.money || '0';

			// 更新图表数据
			nextTick(() => {
				initCharts(res.data);
			});
		} else {
			ElMessage.error(res.msg || '数据获取失败');
			// 使用默认数据初始化图表
			initDefaultCharts();
		}
	} catch (error: any) {
		console.error('获取首页数据失败:', error);
		// 根据错误类型显示不同的提示信息
		if (error.response) {
			// 服务器返回了错误状态码
			switch (error.response.status) {
				case 500:
					ElMessage.error('服务器内部错误，请联系管理员');
					// 检查是否因为token问题导致的错误
					if (error.response.data && error.response.data.message && error.response.data.message.includes('Token')) {
						ElMessage.error('Token验证失败，请重新登录');
						// 清除本地存储的token并跳转到登录页
						Session.clear();
						window.location.href = '/';
					}
					break;
				case 502:
					ElMessage.error('网关错误');
					break;
				case 503:
					ElMessage.error('服务不可用');
					break;
				default:
					ElMessage.error(`请求失败: ${error.response.statusText}`);
			}
		} else if (error.request) {
			// 请求已发出但没有收到响应
			ElMessage.error('网络连接失败，请检查网络');
		} else {
			// 其他错误
			ElMessage.error('请求失败: ' + (error.message || '未知错误'));
		}
		// 使用默认数据初始化图表
		initDefaultCharts();
	}
};

// 初始化 echarts
const initCharts = (data: any) => {
	// 销毁之前的图表实例
	state.myCharts.forEach((chart: any) => {
		chart.dispose();
	});
	state.myCharts = [];

	// 柱状图 - 显示每日预约人数
	const homeLineChart = echarts.init(homeLineRef.value);
	const barOption = {
		title: {
			text: '近7日预约情况',
			left: 'center',
			textStyle: {
				color: '#666',
				fontSize: 14,
				fontWeight: 'normal',
			},
		},
		tooltip: {
			trigger: 'axis',
			axisPointer: {
				type: 'shadow',
			},
		},
		grid: {
			top: '20%',
			left: '3%',
			right: '4%',
			bottom: '15%',
			containLabel: true,
		},
		xAxis: [
			{
				type: 'category',
				data: data.day && data.day.time ? data.day.time.map((item: string) => item.substr(5)) : [], // 只显示月日
				axisTick: {
					alignWithLabel: true,
				},
				axisLine: {
					lineStyle: {
						color: '#ccc',
					},
				},
				axisLabel: {
					color: '#666',
					fontSize: 12,
				},
			},
		],
		yAxis: [
			{
				type: 'value',
				axisLine: {
					show: false,
				},
				axisLabel: {
					color: '#666',
					fontSize: 12,
				},
				splitLine: {
					lineStyle: {
						type: 'dashed',
						color: '#eee',
					},
				},
			},
		],
		series: [
			{
				name: '预约人数',
				type: 'bar',
				barWidth: '45%',
				data: data.day && data.day.num ? data.day.num : [],
				itemStyle: {
					color: {
						type: 'linear',
						x: 0,
						y: 0,
						x2: 0,
						y2: 1,
						colorStops: [
							{ offset: 0, color: '#83bff6' },
							{ offset: 0.5, color: '#188df0' },
							{ offset: 1, color: '#188df0' },
						],
					},
					shadowColor: 'rgba(0, 0, 0, 0.1)',
					shadowBlur: 10,
				},
				emphasis: {
					itemStyle: {
						color: {
							type: 'linear',
							x: 0,
							y: 0,
							x2: 0,
							y2: 1,
							colorStops: [
								{ offset: 0, color: '#a3cff6' },
								{ offset: 0.7, color: '#289df0' },
								{ offset: 1, color: '#289df0' },
							],
						},
					},
				},
			},
		],
	};

	homeLineChart.setOption(barOption);
	state.myCharts.push(homeLineChart);

	// 折线图 - 显示每日收入
	const homePieChart = echarts.init(homePieRef.value);
	const lineOption = {
		title: {
			text: '近7日收入情况',
			left: 'center',
			textStyle: {
				color: '#666',
				fontSize: 14,
				fontWeight: 'normal',
			},
		},
		tooltip: {
			trigger: 'axis',
		},
		grid: {
			top: '20%',
			left: '3%',
			right: '4%',
			bottom: '15%',
			containLabel: true,
		},
		xAxis: {
			type: 'category',
			data: data.price && data.price.time ? data.price.time.map((item: string) => item.substr(5)) : [], // 只显示月日
			axisLine: {
				lineStyle: {
					color: '#ccc',
				},
			},
			axisLabel: {
				color: '#666',
				fontSize: 12,
			},
		},
		yAxis: {
			type: 'value',
			axisLine: {
				show: false,
			},
			axisLabel: {
				color: '#666',
				fontSize: 12,
			},
			splitLine: {
				lineStyle: {
					type: 'dashed',
					color: '#eee',
				},
			},
		},
		series: [
			{
				name: '收入金额',
				type: 'line',
				smooth: true,
				showSymbol: true,
				symbolSize: 6,
				lineStyle: {
					width: 3,
					color: {
						type: 'linear',
						x: 0,
						y: 0,
						x2: 1,
						y2: 0,
						colorStops: [
							{ offset: 0, color: '#83bff6' },
							{ offset: 1, color: '#188df0' },
						],
					},
				},
				areaStyle: {
					opacity: 0.3,
					color: {
						type: 'linear',
						x: 0,
						y: 0,
						x2: 0,
						y2: 1,
						colorStops: [
							{ offset: 0, color: '#83bff6' },
							{ offset: 1, color: 'rgba(24, 141, 240, 0.1)' },
						],
					},
				},
				data: data.price && data.price.num ? data.price.num : [],
			},
		],
	};

	homePieChart.setOption(lineOption);
	state.myCharts.push(homePieChart);
};

// 初始化默认图表（当API失败时使用）
const initDefaultCharts = () => {
	// 销毁之前的图表实例
	state.myCharts.forEach((chart: any) => {
		chart.dispose();
	});
	state.myCharts = [];

	// 默认数据
	const defaultData = {
		day: {
			time: ['2025-08-18', '2025-08-19', '2025-08-20', '2025-08-21', '2025-08-22', '2025-08-23', '2025-08-24'],
			num: [0, 0, 0, 0, 0, 0, 0],
		},
		price: {
			time: ['2025-08-18', '2025-08-19', '2025-08-20', '2025-08-21', '2025-08-22', '2025-08-23', '2025-08-24'],
			num: [0, 200, 0, 0, 0, 0, 0],
		},
	};

	// 柱状图 - 显示每日预约人数
	const homeLineChart = echarts.init(homeLineRef.value);
	const barOption = {
		title: {
			text: '近7日预约情况',
			left: 'left',
			textStyle: {
				color: '#666',
				fontSize: 14,
				fontWeight: 'normal',
			},
		},
		tooltip: {
			trigger: 'axis',
			axisPointer: {
				type: 'shadow',
			},
		},
		grid: {
			top: '20%',
			left: '3%',
			right: '4%',
			bottom: '15%',
			containLabel: true,
		},
		xAxis: [
			{
				type: 'category',
				data: defaultData.day.time.map((item: string) => item.substr(5)), // 只显示月日
				axisTick: {
					alignWithLabel: true,
				},
				axisLine: {
					lineStyle: {
						color: '#ccc',
					},
				},
				axisLabel: {
					color: '#666',
					fontSize: 12,
				},
			},
		],
		yAxis: [
			{
				type: 'value',
				axisLine: {
					show: false,
				},
				axisLabel: {
					color: '#666',
					fontSize: 12,
				},
				splitLine: {
					lineStyle: {
						type: 'dashed',
						color: '#eee',
					},
				},
			},
		],
		series: [
			{
				name: '预约人数',
				type: 'bar',
				barWidth: '45%',
				data: defaultData.day.num,
				itemStyle: {
					color: {
						type: 'linear',
						x: 0,
						y: 0,
						x2: 0,
						y2: 1,
						colorStops: [
							{ offset: 0, color: '#83bff6' },
							{ offset: 0.5, color: '#188df0' },
							{ offset: 1, color: '#188df0' },
						],
					},
					shadowColor: 'rgba(0, 0, 0, 0.1)',
					shadowBlur: 10,
				},
				emphasis: {
					itemStyle: {
						color: {
							type: 'linear',
							x: 0,
							y: 0,
							x2: 0,
							y2: 1,
							colorStops: [
								{ offset: 0, color: '#a3cff6' },
								{ offset: 0.7, color: '#289df0' },
								{ offset: 1, color: '#289df0' },
							],
						},
					},
				},
			},
		],
	};

	homeLineChart.setOption(barOption);
	state.myCharts.push(homeLineChart);

	// 折线图 - 显示每日收入
	const homePieChart = echarts.init(homePieRef.value);
	const lineOption = {
		title: {
			text: '近7日收入情况',
			left: 'left',
			textStyle: {
				color: '#666',
				fontSize: 14,
				fontWeight: 'normal',
			},
		},
		tooltip: {
			trigger: 'axis',
		},
		grid: {
			top: '20%',
			left: '3%',
			right: '4%',
			bottom: '15%',
			containLabel: true,
		},
		xAxis: {
			type: 'category',
			data: defaultData.price.time.map((item: string) => item.substr(5)), // 只显示月日
			axisLine: {
				lineStyle: {
					color: '#ccc',
				},
			},
			axisLabel: {
				color: '#666',
				fontSize: 12,
			},
		},
		yAxis: {
			type: 'value',
			axisLine: {
				show: false,
			},
			axisLabel: {
				color: '#666',
				fontSize: 12,
			},
			splitLine: {
				lineStyle: {
					type: 'dashed',
					color: '#eee',
				},
			},
		},
		series: [
			{
				name: '收入金额',
				type: 'line',
				smooth: true,
				showSymbol: true,
				symbolSize: 6,
				lineStyle: {
					width: 3,
					color: {
						type: 'linear',
						x: 0,
						y: 0,
						x2: 1,
						y2: 0,
						colorStops: [
							{ offset: 0, color: '#83bff6' },
							{ offset: 1, color: '#188df0' },
						],
					},
				},
				areaStyle: {
					opacity: 0.3,
					color: {
						type: 'linear',
						x: 0,
						y: 0,
						x2: 0,
						y2: 1,
						colorStops: [
							{ offset: 0, color: '#83bff6' },
							{ offset: 1, color: 'rgba(24, 141, 240, 0.1)' },
						],
					},
				},
				data: defaultData.price.num,
			},
		],
	};

	homePieChart.setOption(lineOption);
	state.myCharts.push(homePieChart);
};

// 页面加载时初始化图表
onMounted(() => {
	nextTick(() => {
		getDataList();
		getAppointmentList();
		getDepartmentList();
		getDoctorList();
	});
});

// 监听窗口变化，自适应图表大小
watch(
	() => themeConfig.value.isCollapse,
	() => {
		nextTick(() => {
			setTimeout(() => {
				state.myCharts.forEach((v: any) => {
					v.resize();
				});
			}, 300);
		});
	}
);

// 页面激活时重置图表大小
onActivated(() => {
	nextTick(() => {
		state.myCharts.forEach((v: any) => {
			v.resize();
		});
	});
});
</script>

<style scoped lang="scss">
$homeNavLengh: 8;
.home-container {
	overflow: hidden;
	.home-card-one,
	.home-card-two,
	.home-card-three {
		.home-card-item {
			width: 100%;
			height: 130px;
			border-radius: 4px;
			transition: all ease 0.3s;
			padding: 20px;
			overflow: hidden;
			background: var(--el-color-white);
			color: var(--el-text-color-primary);
			border: 1px solid var(--next-border-color-light);
			&:hover {
				box-shadow: 0 2px 12px var(--next-color-dark-hover);
				transition: all ease 0.3s;
			}
			&-icon {
				width: 70px;
				height: 70px;
				border-radius: 100%;
				flex-shrink: 1;
				i {
					color: var(--el-text-color-placeholder);
				}
			}
			&-title {
				font-size: 15px;
				font-weight: bold;
				height: 30px;
				margin-bottom: 10px;
			}
		}
	}
	.home-card-one {
		@for $i from 0 through 3 {
			.home-one-animation#{$i} {
				width: 100%;
				opacity: 0;
				animation-name: error-num;
				animation-duration: 0.5s;
				animation-fill-mode: forwards;
				animation-delay: calc($i/5) + s;
			}
		}
	}
	.home-card-two,
	.home-card-three {
		.home-card-item {
			height: 320px;
			width: 100%;
			overflow: hidden;
			.home-monitor {
				height: 100%;
				.flex-warp-item {
					width: 25%;
					height: 111px;
					display: flex;
					.flex-warp-item-box {
						margin: auto;
						text-align: center;
						color: var(--el-text-color-primary);
						display: flex;
						border-radius: 5px;
						background: var(--next-bg-color);
						cursor: pointer;
						transition: all 0.3s ease;
						&:hover {
							background: var(--el-color-primary-light-9);
							transition: all 0.3s ease;
						}
					}
					@for $i from 0 through $homeNavLengh {
						.home-animation#{$i} {
							opacity: 0;
							animation-name: error-num;
							animation-duration: 0.5s;
							animation-fill-mode: forwards;
							animation-delay: calc($i/10) + s;
						}
					}
				}
			}
		}
	}

	.top-three {
		font-weight: bold;
		color: #e6a23c;
	}

	.department-name {
		display: inline-block;
		width: 100%;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.ranking-number {
		display: inline-block;
		width: 30px;
		height: 30px;
		line-height: 30px;
		border-radius: 50%;
		background-color: #f6a2a5;
		color: white;
		text-align: center;
		font-weight: bold;
	}
}
</style>
